home *** CD-ROM | disk | FTP | other *** search
- /*
- ** listbox.c
- **
- ** Pictor, Version 1.51, Copyright (c) 1992-94 SoftCircuits
- ** Redistributed by permission.
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include "pictor.h"
-
- #define UPDATE_NOUPDATE 0
- #define UPDATE_CURSOR 1
- #define UPDATE_WINDOW 2
-
- int _PL_lbcolwidth = 12;
- int _PL_lbrows = 8;
- int _PL_lbcols = 4;
-
-
- /*
- ** Allows the user to select from a list of items using the cursor
- ** keys. TRUE is returned and *selection is set to the index of the
- ** selected item if the user pressed Enter. FALSE is returned and
- ** *selection is unchanged if Escape is pressed or numitems == 0.
- **
- ** This function could be called recursively if it is active and
- ** help is selected.
- */
- int listbox(char **items,int numitems,int *selection,
- char *title,COLORSTRUCT *colors)
- {
- int done = FALSE,update = UPDATE_WINDOW,leftcol = 0;
- int i,j,key,top,left,row,col,newsel,oldsel = 0;
-
- newsel = *selection;
-
- if(numitems == 0)
- return(FALSE);
-
- top = center(_PL_lbrows + 2,_PL_rows);
- left = center((_PL_lbcols * (_PL_lbcolwidth + 2)) + 2,_PL_columns);
-
- wopen(top,left,_PL_lbrows + 2,(_PL_lbcols * (_PL_lbcolwidth + 2)) + 2,
- colors->normal,WO_STATICMEM | WO_SHADOW);
- wtitle(title);
-
- while(!done) {
-
- if(update != UPDATE_NOUPDATE) {
-
- if((newsel / _PL_lbrows) < leftcol) {
- leftcol = (newsel / _PL_lbrows);
- update = UPDATE_WINDOW;
- }
- else if((newsel / _PL_lbrows) >= (leftcol + _PL_lbcols)) {
- leftcol = (newsel / _PL_lbrows) - (_PL_lbcols - 1);
- update = UPDATE_WINDOW;
- }
-
- if(update == UPDATE_WINDOW) {
-
- vcolor(colors->normal);
- i = (leftcol * _PL_lbrows);
-
- for(col = 0;col < _PL_lbcols;col++) {
- for(row = 0;row < _PL_lbrows;row++,i++) {
- setwpos(row + 1,(col * (_PL_lbcolwidth + 2)) + 1);
- if(i < numitems) {
- wputc(' ');
- for(j = 0;j < _PL_lbcolwidth && items[i][j];j++) {
- wputc(items[i][j]);
- }
- wrepc(' ',(_PL_lbcolwidth + 1) - j);
- }
- else {
- wrepc(' ',_PL_lbcolwidth + 2);
- }
- }
- }
- }
- else {
- /* unhilight old selection */
- i = ((oldsel / _PL_lbrows) - leftcol);
- setwpos((oldsel % _PL_lbrows) + 1,(i * (_PL_lbcolwidth + 2)) + 1);
- wrepa(colors->normal,_PL_lbcolwidth + 2);
- }
-
- /* hilight new selection */
- i = ((newsel / _PL_lbrows) - leftcol);
- setwpos((newsel % _PL_lbrows) + 1,(i * (_PL_lbcolwidth + 2)) + 1);
- wrepa(colors->select,_PL_lbcolwidth + 2);
-
- update = UPDATE_NOUPDATE;
- oldsel = newsel;
- }
- switch(key = kbdread()) {
- case ENTER_KEY:
- *selection = newsel;
- done = TRUE;
- break;
- case ESCAPE_KEY:
- done = TRUE;
- break;
- case UP_KEY:
- if(newsel > 0) {
- newsel--;
- update = UPDATE_CURSOR;
- }
- else beep();
- break;
- case DOWN_KEY:
- case SPACE_BAR:
- if(newsel < (numitems - 1)) {
- newsel++;
- update = UPDATE_CURSOR;
- }
- else beep();
- break;
- case LEFT_KEY:
- if(newsel > 0) {
- if(newsel > _PL_lbrows) {
- newsel -= _PL_lbrows;
- }
- else {
- newsel = 0;
- }
- update = UPDATE_CURSOR;
- }
- else beep();
- break;
- case RIGHT_KEY:
- if(newsel < (numitems - 1)) {
- if(newsel < (numitems - _PL_lbrows)) {
- newsel += _PL_lbrows;
- }
- else {
- newsel = (numitems - 1);
- }
- update = UPDATE_CURSOR;
- }
- else beep();
- break;
- case PGUP_KEY:
- if(newsel > 0) {
- if(newsel > (_PL_lbrows * _PL_lbcols)) {
- newsel -= (_PL_lbrows * _PL_lbcols);
- if(leftcol > _PL_lbcols)
- leftcol -= _PL_lbcols;
- else
- leftcol = 0;
- update = UPDATE_WINDOW;
- }
- else {
- newsel = 0;
- update = UPDATE_CURSOR;
- }
- }
- else beep();
- break;
- case PGDN_KEY:
- if(newsel < (numitems - 1)) {
- if(newsel < (numitems - (_PL_lbrows * _PL_lbcols))) {
- newsel += (_PL_lbrows * _PL_lbcols);
- leftcol += _PL_lbcols;
- update = UPDATE_WINDOW;
- }
- else {
- newsel = (numitems - 1);
- update = UPDATE_CURSOR;
- }
- }
- else beep();
- break;
- case HOME_KEY:
- if(newsel > 0) {
- newsel = 0;
- update = UPDATE_CURSOR;
- }
- break;
- case END_KEY:
- if(newsel < (numitems - 1)) {
- newsel = (numitems - 1);
- update = UPDATE_CURSOR;
- }
- break;
- case F1_KEY:
- if(_PL_helpfunc != NULL)
- _PL_helpfunc(_PL_helpcontext);
- else beep();
- break;
- default:
- /* jump to selection if first letter pressed */
- kbdflush();
- key = toupper(key & 0xFF);
- if(isalnum(key)) {
- for(i = newsel + 1;i < numitems && !update;i++) {
- if(key == toupper(*items[i])) {
- newsel = i;
- update = UPDATE_CURSOR;
- }
- }
- for(i = 0;i <= newsel && !update;i++) {
- if(key == toupper(*items[i])) {
- newsel = i;
- update = UPDATE_CURSOR;
- }
- }
- }
- if(!update)
- beep();
- break;
- }
- }
- wclose();
-
- /* return TRUE if enter pressed */
- return(key == ENTER_KEY);
-
- } /* listbox */
-